<template>
  <div class="com-container">
    <div class="title" :style="comStyle">
      <span>{{ "☺    " + showTitle }}</span>
      <button @click="exportExcel">导出</button>
      <span
        class="iconfont title-icon"
        :style="comStyle"
        @click="showChoice = !showChoice"
        >&#xe6eb;</span
      >
      <div class="select-con" v-show="showChoice">
        <div
          class="select-item"
          v-for="item in selectTypes"
          :style="marginStyle"
          :key="item.key"
          @click="handleSelect(item.key)"
        >
          {{ item.text }}
        </div>
      </div>
    </div>
    <div class="com-chart" ref="trend_ref"></div>
  </div>
</template>

<script>
import { mapState } from "vuex";
import { getThemeValue } from '@/utils/theme_utils';
import * as XLSX from "xlsx";

export default {
  data() {
    return {
      chartInstance: null,
      tableData: null,
      allData: null, //从服务器中获取的所有数据
      showChoice: false, // 是否显示可选项
      choiceType: "map", //显示的数据类型
      titleFontSize: 0, //指明标题的字体大小
      timeArr: null,
    };
  },
  created() {
    // 第一个为回调函数的标识，第二个调用的是什么函数
    // 在组件创建完成之后 进行回调函数的注册
    this.$socket.registerCallBack("trendData", this.getData);
  },
  mounted() {
    //调用初始化图表的方法
    this.initChart();
    // this.getData();
    // 往服务端发数据
    // 发送数据，告诉服务器，我现在需要数据
    this.$socket.send({
      action: "getData",
      socketType: "trendData",
      chartName: "trend",
      // 获取数据value可以不传递
      value: "",
    });
    window.addEventListener("resize", this.screenAdapter);
    // 在屏幕不发生变化的时候，自动触发
    this.screenAdapter();
    // this.exportExcel()
  },
  destroyed() {
    // 取消监听
    window.removeEventListener("resize".this.screenAdapter);
    // 在组件销毁的时候，进行回调函数的销毁
    this.$scoket.unRegisterCallBack("trendData");
  },

  methods: {
    initChart() {
      // 得到一个echarts的实例对象
      this.chartInstance = this.$echarts.init(this.$refs.trend_ref, this.theme);
      const initOption = {
        // 调整图标的位置
        grid: {
          left: "3%",
          top: "35%",
          right: "4%",
          botton: "1%",
          containLabel: true,
        },
        tooltip: {
          trigger: "axis",
        },
        // 图例的位置和形状
        legend: {
          left: 20,
          top: "15%",
          icon: "circle",
        },
        xAxis: {
          type: "category",
          // 与y轴是否需要具备间隙
          boundaryGap: false,
        },
        yAxis: {
          type: "value",
        },
      };
      this.chartInstance.setOption(initOption);
    },
    // getData() {
    //   this.$http({
    //     method: "get",
    //     url: "/trend",
    //   }).then((res) => {
    //     const { data: ret } = res;
    //     this.allData = ret;
    //     // console.log(ret);
    //     this.updateChart();
    //   });
    // },
    getData(ret) {
      this.allData = ret;
      this.updateChart();
    },
    updateChart() {
      // 半透明的颜色值
      const colorArr1 = [
        "rgba(11, 168, 44, 0.5)",
        "rgba(44, 110, 255, 0.5)",
        "rgba(22, 242, 217, 0.5)",
        "rgba(254, 33, 30, 0.5)",
        "rgba(250, 105, 0, 0.5)",
      ];
      // 全透明的颜色值
      const colorArr2 = [
        "rgba(11, 168, 44, 0)",
        "rgba(44, 110, 255, 0)",
        "rgba(22, 242, 217, 0)",
        "rgba(254, 33, 30, 0)",
        "rgba(250, 105, 0, 0)",
      ];
      // 处理数据
      // 类目轴的数据
      this.timeArr = this.allData.common.month;
      // y轴的数据 series下的数据 每个月对应的数据
      const valueArr = this.allData[this.choiceType].data;

      const seriesArr = valueArr.map((item, index) => {
        return {
          name: item.name,
          type: "line",
          data: item.data,
          stack: this.choiceType,
          // 分隔区域颜色
          areaStyle: {
            // 颜色渐变
            color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: colorArr1[index],
              }, // %0的颜色值
              {
                offset: 1,
                color: colorArr2[index],
              }, // 100%的颜色值
            ]),
          },
        };
      });

      // console.log(valueArr);
      // 图例的数据
      const legendArr = valueArr.map((item) => {
        return item.name;
      });
      const dataOption = {
        xAxis: {
          data: this.timeArr,
        },

        legend: {
          data: legendArr,
        },
        series: seriesArr,
      };
      this.chartInstance.setOption(dataOption);
    },
    screenAdapter() {
      // 得到显示图标的容器的宽度
      this.titleFontSize = (this.$refs.trend_ref.offsetWidth / 100) * 3.6;
      const adapterOption = {
        legend: {
          // 控制图例的宽度
          itemWidth: this.titleFontSize,
          // 控制图例的高度
          itemHeight: this.titleFontSize,
          //字体间距
          itemGap: this.titleFontSize,
          // 图标文字自适应
          textStyle: {
            fontSize: this.titleFontSize / 2,
          },
        },
      };
      this.chartInstance.setOption(adapterOption);
      this.chartInstance.resize();
    },
    handleSelect(currentType) {
      this.choiceType = currentType;
      this.updateChart();
      this.showChoice = false;
    },
    // 将折线图图的数据转换成表格需要的数据
    dataConversion() {
      // 获取折线图的数据
      let chartData = this.chartInstance.getOption().series;

      // 将折线图数据转换为表格数据
      // console.log(chartData);

      // this.tableData = this.timeArr.map((item, index) => {
      //   // 动态的计算属性名

      //   const  dynamicKey =   `${chartData[0].name}的折线图数据`;
      //   return {
      //     date: item, // 将 x 轴的数据作为表格的列名
      //     [dynamicKey]: chartData[0].data[index], // 将 y 轴的数据作为表格的行数据
      //     // 第二条线: chartData[1].data[index],
      //   };
      // });

      this.tableData = chartData.map((item, index) => {
        // 动态的计算属性名
        const dynamicKey = `${chartData[index].name}的折线图数据`;
        return {
          data: this.timeArr[index], //在一月份的时候需要将每个属性一月份的数据给他
          // 如何让属性根据数组下标的长度自增
          // [dynamicKey]: item.data[0], //就算下标为0，在execl里面依然是输出第一个数组下标在第item数组下标的位置
          [dynamicKey]: ["7.58", "23.66", "39.78", "30.20", "25.72"],
        };
      });
      // console.log('tableData的值是'+JSON.stringify( this.tableData));
    },

    exportExcel() {
      this.dataConversion();
      const chartData = this.tableData; // 获取折线图的数据，这里需要根据你的实际情况自行实现

      // 创建一个空的工作簿
      const workbook = XLSX.utils.book_new();

      // 将折线数据转换为工作表
      const worksheet = XLSX.utils.json_to_sheet(chartData);

      // 将工作表添加到工作簿
      XLSX.utils.book_append_sheet(workbook, worksheet, "导出成功");

      // 将工作簿转换为二进制数据
      const excelData = XLSX.write(workbook, {
        type: "binary",
        bookType: "xlsx",
      });

      // 将二进制数据转换为 Blob 对象
      const blob = new Blob([this.s2ab(excelData)], {
        type: "application/octet-stream",
      });

      // 创建下载链接
      const url = URL.createObjectURL(blob);

      // 创建一个隐藏的下载链接并触发点击事件进行下载
      const link = document.createElement("a");
      link.href = url;
      link.download = "折线数据.xlsx";
      link.style.display = "none";
      document.body.appendChild(link);
      link.click();

      // 清理下载链接
      document.body.removeChild(link);
      URL.revokeObjectURL(url);
    },
    s2ab(s) {
      const buf = new ArrayBuffer(s.length);
      const view = new Uint8Array(buf);
      for (let i = 0; i < s.length; i++) {
        view[i] = s.charCodeAt(i) & 0xff;
      }
      return buf;
    },
  },
  // 计算属性
  computed: {
    selectTypes() {
      if (!this.allData) {
        return [];
      } else {
        return this.allData.type.filter((item) => {
          // 返回的时候把当前的选择类型的值去除就可以了
          return item.key !== this.choiceType;
        });
      }
    },
    showTitle() {
      if (!this.allData) {
        return;
      } else {
        return this.allData[this.choiceType].title;
      }
    },
    // 设置给标题的样式
    comStyle() {
      return {
        fontSize: this.titleFontSize + "px",
        color: getThemeValue(this.theme).titleColor 
      };
    },
    // 让下拉框的文字靠右
    marginStyle() {
      return {
        marginLeft: this.titleFontSize * 1.3 + "px",
      };
    },
    ...mapState(["theme"]),
  },
  watch: {
    theme() {
      this.chartInstance.dispose(); //销毁当前图表
      this.initChart(); //重新以最新的主题名称切换初始化图表对象
      this.screenAdapter(); //完成屏幕的适配
      this.updateChart(); //更新图表的展示
    },
  },
};
</script>
<style lang="less" scoped>
.title {
  position: absolute;
  left: 20px;
  top: 20px;
  z-index: 10;
  color: white;
  .title-icon {
    margin-right: 10px;
    // 更改鼠标箭头
    cursor: pointer;
  }
  .select-con {
    background-color: #222733;
  }
}
</style>